using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Geoconcepts.SemanticServices;
using Geoconcepts.Types;

namespace Geoconcepts.Acquisition
{
    /// <summary>
    /// Class to include Geoconcepts processing over SemanticServices for creation of Geoconcepts OWL
    /// </summary
    public class SemanticConversion
    {
        public byte [] ConvertGeoconceptsToOWL(GeoconceptsDataSet dtsGeoconcepts)
        {
            #region Variables
            byte[] owlFile = null;
            // Ontology Namespaces
            string strGCNameSpace = "http://www.geospatialmeaning.eu/geo-ontologies-survey/GeoConcepts/GeoConcepts_v1.1_20080301Lite.owl#";
            string strSWRL_URL = "http://www.geospatialmeaning.eu/geo-ontologies-survey/GeoConcepts/GeoConcepts_v1.2_20080326Lite_swrl.owl";
            string strGMLNameSpace = "http://www.geospatialmeaning.eu/geo-ontologies-survey/W3C-Geo2007/";
            #endregion Variables
            try
            {
                Reasoner svcReasoner = new Reasoner(strSWRL_URL);
                #region Dataset iteration and ontology population
                foreach (GeoconceptsDataSet.GeoconceptsItemsRow drGeoconcept in dtsGeoconcepts.GeoconceptsItems)
                {
                    svcReasoner.AddIndividual(strGMLNameSpace, "_Feature", strGCNameSpace, drGeoconcept.Geoconcept);

                    #region Polygons and Centroids
                    GeoconceptsDataSet.PolygonsRow[] drPolygons = (GeoconceptsDataSet.PolygonsRow[])
                        dtsGeoconcepts.Polygons.Select("Geoconcept like '" + drGeoconcept.Geoconcept + "'");
                    foreach (GeoconceptsDataSet.PolygonsRow drPolygon in drPolygons)
                    {
                        // geoconcept, where, polygon
                        svcReasoner.AddIndividual(strGMLNameSpace, "Polygon", strGCNameSpace, drPolygon.Polygon);
                        svcReasoner.AddProperty(strGCNameSpace, drGeoconcept.Geoconcept, strGMLNameSpace, "where", strGCNameSpace, drPolygon.Polygon);

                        // polygon, exterior, Linear ring
                        svcReasoner.AddIndividual(strGMLNameSpace, "LinearRing", strGCNameSpace, "lr" + drPolygon.Polygon);
                        svcReasoner.AddProperty(strGCNameSpace, drPolygon.Polygon, strGMLNameSpace, "exterior", strGCNameSpace, "lr" + drPolygon.Polygon);

                        // Linear ring, posList, string "Points"
                        svcReasoner.AddDataTypeProperty(strGCNameSpace, "lr" + drPolygon.Polygon, strGMLNameSpace, "posList", drPolygon.Points);

                        #region Centroids
                        // It is not clear the need of a foreach. But it worked, so...
                        GeoconceptsDataSet.CentroidsRow[] drCentroids =
                            (GeoconceptsDataSet.CentroidsRow[])dtsGeoconcepts.Centroids.Select("Polygon like '" + drPolygon.Points + "'");
                        foreach (GeoconceptsDataSet.CentroidsRow drCentroid in drCentroids)
                        { 
                            // polygon, hasCentroid, Point
                            svcReasoner.AddIndividual(strGMLNameSpace, "Point", strGCNameSpace, drCentroid.Centroid);
                            svcReasoner.AddProperty(strGMLNameSpace, drPolygon.Polygon, strGCNameSpace, "hasCentroid", strGCNameSpace, drCentroid.Centroid);

                            // point, pos, string "Point"
                            svcReasoner.AddDataTypeProperty(strGCNameSpace, drCentroid.Centroid, strGMLNameSpace, "pos", drCentroid.Point);
                        }
                        #endregion Centroids
                    }
                    #endregion Polygons and Centroids
                }

                #region Relationships
                foreach (GeoconceptsDataSet.GeoconceptsRelationsRow drGCRelation in dtsGeoconcepts.GeoconceptsRelations)
                {
                    // geoconcept source, relationship, geoconcept target
                    svcReasoner.AddProperty(strGCNameSpace, drGCRelation.Geoconcept, strGCNameSpace, drGCRelation.RelationShip, strGCNameSpace, drGCRelation.GeoconceptTarget);
                }
                #endregion Relationships

                // Execute inferences over ABox according to TBox an return an OWL file with the result
                owlFile = svcReasoner.ReturnInferencedGraph();

                #endregion Dataset iteration and ontology population

                return owlFile;

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
